SVM patch to reverse the logic of the general1 intercepts for easier
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 17 May 2006 22:51:39 +0000 (23:51 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 17 May 2006 22:51:39 +0000 (23:51 +0100)
reading, also add the INVD intercept with print/eip increment only.

Signed-off-by: Tom Woller <thomas.woller@amd.com>
Signed-off-by: Mats Petersson <mats.petersson@amd.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c

index e95cafd9a09a0a879b30cae136a3a24a3b32e0a3..cf84b2fabff04ef2de5fed68ae8b0754aedad779 100644 (file)
@@ -1852,7 +1852,8 @@ static int svm_cr_access(struct vcpu *v, unsigned int cr, unsigned int type,
         break;
 
     case INSTR_SMSW:
-        svm_dump_inst(svm_rip2pointer(vmcb));
+        if (svm_dbg_on)
+            svm_dump_inst(svm_rip2pointer(vmcb));
         value = v->arch.hvm_svm.cpu_shadow_cr0;
         gpreg = decode_src_reg(prefix, buffer[index+2]);
         set_reg(gpreg, value, regs, vmcb);
@@ -1989,9 +1990,25 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
 }
 
 
-static inline void svm_vmexit_do_mwait(void)
+static void svm_vmexit_do_invd(struct vmcb_struct *vmcb)
 {
-}
+    int  inst_len;
+    
+    /* Invalidate the cache - we can't really do that safely - maybe we should 
+     * WBINVD, but I think it's just fine to completely ignore it - we should 
+     * have cache-snooping that solves it anyways. -- Mats P. 
+     */
+
+    /* Tell the user that we did this - just in case someone runs some really weird 
+     * operating system and wants to know why it's not working as it should...
+     */
+    printk("INVD instruction intercepted - ignored\n");
+    
+    inst_len = __get_instruction_length(vmcb, INSTR_INVD, NULL);
+    __update_guest_eip(vmcb, inst_len);
+}    
+        
+
 
 
 #ifdef XEN_DEBUGGER
@@ -2053,7 +2070,7 @@ void svm_handle_invlpg(const short invlpga, struct cpu_user_regs *regs)
         __update_guest_eip(vmcb, inst_len);
 
         /* 
-         * The address is implicit on this instruction At the moment, we don't
+         * The address is implicit on this instruction. At the moment, we don't
          * use ecx (ASID) to identify individual guests pages 
          */
         g_vaddr = regs->eax;
@@ -2703,6 +2720,11 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs regs)
         raise_softirq(SCHEDULE_SOFTIRQ);
         break;
 
+
+    case VMEXIT_INVD:
+        svm_vmexit_do_invd(vmcb);
+        break;
+
     case VMEXIT_GDTR_WRITE:
         printk("WRITE to GDTR\n");
         break;
index 91697b9064907cc8496c7742aff0b5e00c3ea604..4a61ff62bee4cfd21bed12d0b2f04441a5d77462 100644 (file)
@@ -117,16 +117,12 @@ static int construct_vmcb_controls(struct arch_svm_struct *arch_svm)
 
     /* mask off all general 1 intercepts except those listed here */
     vmcb->general1_intercepts = 
-        ~(GENERAL1_INTERCEPT_CR0_SEL_WRITE | GENERAL1_INTERCEPT_VINTR      | 
-          GENERAL1_INTERCEPT_IDTR_READ     | GENERAL1_INTERCEPT_IDTR_WRITE | 
-          GENERAL1_INTERCEPT_GDTR_READ     | GENERAL1_INTERCEPT_GDTR_WRITE |
-          GENERAL1_INTERCEPT_LDTR_READ     | GENERAL1_INTERCEPT_LDTR_WRITE | 
-          GENERAL1_INTERCEPT_TR_READ       | GENERAL1_INTERCEPT_TR_WRITE   |
-          GENERAL1_INTERCEPT_RDTSC         | GENERAL1_INTERCEPT_PUSHF      |
-          GENERAL1_INTERCEPT_SWINT         | GENERAL1_INTERCEPT_POPF       | 
-          GENERAL1_INTERCEPT_IRET          | GENERAL1_INTERCEPT_PAUSE      |
-          GENERAL1_INTERCEPT_TASK_SWITCH
-        );
+        GENERAL1_INTERCEPT_INTR         | GENERAL1_INTERCEPT_NMI         |
+        GENERAL1_INTERCEPT_SMI          | GENERAL1_INTERCEPT_INIT        |
+        GENERAL1_INTERCEPT_CPUID        | GENERAL1_INTERCEPT_INVD        |
+        GENERAL1_INTERCEPT_HLT          | GENERAL1_INTERCEPT_INVLPG      | 
+        GENERAL1_INTERCEPT_INVLPGA      | GENERAL1_INTERCEPT_IOIO_PROT   |
+        GENERAL1_INTERCEPT_MSR_PROT     | GENERAL1_INTERCEPT_SHUTDOWN_EVT;
 
     /* turn on the general 2 intercepts */
     vmcb->general2_intercepts =